<?php
	
	namespace Aspic\File;
	
	use Aspic as A;
	
	class File {
		protected $url;
		protected $fp = false;
		protected $flockWait;

		function __construct($url, $flockWait = 1000) {
			$this->url = $url;
			$this->flockWait = intval($flockWait);
		}

		function  __call($func,$fArgs) {
			$realFuncName = 'f'.$func; // fopen fputs ftell fgets fxxx ...
			
			if(function_exists($realFuncName)) {
				$args = array($this->fp);
				
				foreach($fArgs as $v)
					$args[] = $v;
			
				$ret = call_user_func_array($realFuncName,$args);
				
				return $ret;
			}
			else
				return false;
		}
		
		public function open($t,$l = LOCK_SH) { // Ouvre et verrouille	
			if(!file_exists($this->url) && strpos($t,'a') == -1 && strpos($t,'w') == -1 && strpos($t,'r+') == -1)
				return false;
				
			$fp = fopen($this->url,$t);
			
			if($fp) $this->fp = $fp; else return false;
			
			$canWrite = flock($fp,$l);
			
			$startTime = microtime(true);
			
			while ($canWrite == false AND ((microtime(true) - $startTime) <= $this->flockWait)) {
				usleep(round(rand(0, 100)));
				$canWrite = flock($fp, $l + LOCK_NB);
			}

			if(!$canWrite) return false; else return $fp;
		}
		
		public function close() {
			if($this->fp) {
				fclose($this->fp);
				return true;
			}
			else
				return false;
		}
		
		public static function getLines($path, $waitIfLocked = true) {
			if(!file_exists($path)) {
				throw new A\Exception('File "'.$path.'" does not exists');
			}
			else {
				$fo = fopen($path, 'r');
				$locked = flock($fo, LOCK_SH, $waitIfLocked);
				
				if(!$locked) {
					return false;
				}
				else {
				    $file = file($path, FILE_IGNORE_NEW_LINES);
					
					flock($fo, LOCK_UN);
					fclose($fo);
					
					return $file;
				}
			}
		}
		
		public static function getContents($path, $waitIfLocked = true) {
			if(!file_exists($path)) {
				throw new A\Exception('File "'.$path.'" does not exists');
			}
			else {
				$fo = fopen($path, 'r');
				$locked = flock($fo, LOCK_SH, $waitIfLocked);
				
				if(!$locked) {
					return false;
				}
				else {
					$cts = file_get_contents($path);
					
					flock($fo, LOCK_UN);
					fclose($fo);
					
					return $cts;
				}
			}
		}

		public static function putContents($url, $data, $lockFile = true) {
			if($lockFile) {
				return file_put_contents($url, $data, LOCK_EX);
			}
			else {
				return file_put_contents($url, $data);
			}
		}
		
		public static function appendContents($path, $contents, $lockFile = true) {
			if($lockFile) {
				return file_put_contents($url, $data, LOCK_EX | FILE_APPEND);
			}
			else {
				return file_put_contents($url, $data, FILE_APPEND);
			}
		}
		
		/**
		* This do not support LOCK
		*/
		// public static function getLines($path, $ignoreNewLines = true) {
			// if($ignoreNewLines) {
				// $file = file($path, FILE_IGNORE_NEW_LINES);
			// }
			// else {
				// $file = file($path);
			// }
			
			// return $file;
		// }
	}
	
?>